home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1997 February: Tool Chest / Dev.CD Feb 97 TC.toast / Sample Code / Interapplication Communication / MenuScripter 4.0 / Sources / MSAEGetData.c < prev    next >
Encoding:
Text File  |  1996-07-09  |  19.3 KB  |  735 lines  |  [TEXT/CWIE]

  1. // MSAEGetData.c
  2. //
  3. // Original version by Jon Lansdell and Nigel Humphreys.
  4. // 4.0 and 3.1 updates by Greg Sutton.
  5. // ©Apple Computer Inc 1996, all rights reserved.
  6.  
  7. /*
  8.         Changes for 4.0
  9.  
  10.         29-Feb-96 : GS : Added abiltiy to get properties from menus and menu items.
  11.         29-Feb-96 : GS : Added script properties to application and document objects.
  12. */
  13.  
  14. #include "MSAEGetData.h"
  15.  
  16. #include "MSWindow.h"
  17. #include "MSGlobals.h"
  18. #include "MSAEUtils.h"
  19. #include "MSAppleEvents.h"
  20.  
  21. #include "MSAETextUtils.h"
  22. #include "MSAEWindowUtils.h"
  23. #include "MSAEMenuUtils.h"
  24. #include "MSAccessors.h"
  25. #include "MSAERecording.h"
  26. #include "MSToken.h"
  27. #include "MSScript.h"
  28. #include "MSResultWind.h"
  29.  
  30.  
  31. #include <AEPackObject.h>
  32. #include <Resources.h>
  33. #ifdef THINK_C
  34.     #include "PLStrs.h"
  35. #else
  36.     #include <PLStringFuncs.h>
  37. #endif
  38.  
  39.  
  40.     // Globals
  41. extern short        gRefNum;
  42.  
  43. // -----------------------------------------------------------------------
  44. //        Name:             DoGetData
  45. //        Purpose:        Handles the GetData AppleEvent.
  46. // -----------------------------------------------------------------------
  47.  
  48. pascal OSErr     DoGetData(const AppleEvent    *theAppleEvent,
  49.                                 AppleEvent    *reply,
  50.                                 long        handlerRefCon)
  51. #ifdef __MWERKS__
  52.     #pragma unused (handlerRefCon)
  53. #endif
  54.  
  55.     AEDesc        directObj = {typeNull, NULL},
  56.                 result = {typeNull, NULL};
  57.     Size        actualSize;
  58.     DescType    returnedType;
  59.     DescType    aWantType;
  60.     OSErr        err;
  61.     
  62.         // extract the direct object, which is the object
  63.         // whose data is to be returned
  64.     err = AEGetParamDesc(theAppleEvent, keyDirectObject, typeWildCard, &directObj);
  65.     if (noErr != err) goto done;
  66.         
  67.         // now the get the type of data wanted - optional
  68.     err = AEGetParamPtr( theAppleEvent, keyAERequestedType, typeType,
  69.                                 &returnedType, (Ptr)&aWantType, sizeof( aWantType ), &actualSize );
  70.     if ( noErr != err )
  71.         aWantType = typeWildCard;
  72.         
  73.     err = GotRequiredParams(theAppleEvent);
  74.     if (noErr != err) goto done;
  75.     
  76.         // get the data
  77.     err = HandleGetData( &directObj, aWantType, &result );
  78.         
  79.     err = AddResultToReply(&result, reply, err);
  80.  
  81. done:                
  82.     (void)AEDisposeDesc( &directObj );
  83.     (void)AEDisposeDesc( &result );
  84.         
  85.     return(err);
  86. }    // DoGetData
  87.  
  88.  
  89. // -----------------------------------------------------------------------
  90. //    Name:         HandleGetData
  91. //    Purpose:    Coerces theObj into a token which we understand and
  92. //                extracts the data requested in the token and puts it
  93. //                into dataDesc.
  94. // -----------------------------------------------------------------------
  95.  
  96. OSErr    HandleGetData( AEDesc *theObj, DescType theWantType, AEDesc *result )
  97. {
  98.     TextToken       theTextToken;
  99.     Size            tokenSize;
  100.     AEDesc          objTokenDesc = {typeNull, NULL},
  101.                     itemDesc = {typeNull, NULL},
  102.                     resultDesc = {typeNull, NULL};
  103.     long            index;
  104.     DescType        returnedType;
  105.     OSErr           err;
  106.  
  107.             // Coerce theObj into a token which we can use - 
  108.             //  this may involve converting a list of tokens to a list of property tokens
  109.     if ( typeObjectSpecifier == theObj->descriptorType )
  110.         err = AEResolve( theObj, kAEIDoMinimum, &objTokenDesc );
  111.     else if ( typeNull != theObj->descriptorType )    // Otherwise, just copy it
  112.         err = AEDuplicateDesc( theObj, &objTokenDesc );
  113.     
  114.     if ( noErr != err ) goto done;
  115.     
  116.     switch ( objTokenDesc.descriptorType )
  117.     {
  118.         case typeMyApplProp:
  119.             err = GetApplicationProperty( &objTokenDesc, theWantType, result );
  120.             break;
  121.             
  122.         case typeMyTextProp:
  123.             err = GetTextProperty(&objTokenDesc, result);
  124.             break;
  125.             
  126.         case typeMyWindowProp:
  127.             err = GetWindowProperty(&objTokenDesc, result);
  128.             break;
  129.             
  130.         case typeMyDocumentProp:
  131.             err = GetDocumentProperty( &objTokenDesc, theWantType, result );
  132.             break;
  133.             
  134.         case typeMyMenuProp:
  135.             err = GetMenuProperty( &objTokenDesc, theWantType, result );
  136.             break;
  137.             
  138.         case typeMyMenuItemProp:
  139.             err = GetMenuItemProperty( &objTokenDesc, theWantType, result );
  140.             break;
  141.             
  142.         case typeMyText:
  143.             GetRawDataFromDescriptor( &objTokenDesc, (Ptr)&theTextToken,
  144.                                                 sizeof(theTextToken), &tokenSize );
  145.  
  146.             if ( theWantType == typeChar || theWantType == typeIntlText )
  147.                 err = GetTextTextProperty( &theTextToken, result );
  148.             else                // For OSADoEvent()
  149.                 err = GetTextTokenObjectSpecifier( &theTextToken, result );
  150.             break;
  151.             
  152.         case typeAEList:
  153.             err = AECountItems(&objTokenDesc, &index);
  154.             if (noErr != err) goto done;
  155.     
  156.             for (; index > 0; index--)
  157.             {
  158.                 err = AEGetNthDesc(&objTokenDesc, index, typeWildCard, &returnedType, &itemDesc);
  159.     
  160.                 if (noErr == err)        // Call this function recursively if necessary
  161.                     err = HandleGetData(&itemDesc, theWantType, &resultDesc);
  162.                 
  163.                 if (noErr == err)        // Overwrite item in list with descriptor item
  164.                     err = AEPutDesc(&objTokenDesc, index, &resultDesc);
  165.                                                         // objTokenDesc is just a copy anyway.
  166.                 (void)AEDisposeDesc(&itemDesc);
  167.                 (void)AEDisposeDesc(&resultDesc);
  168.             }
  169.             
  170.             err = AEDuplicateDesc( &objTokenDesc, result );        // Copy list into result
  171.             break;
  172.             
  173.         default:    
  174.             err = AEDuplicateDesc( theObj, result );    // For OSADoEvent()
  175.             break;
  176.     }
  177.  
  178. done:
  179.     (void)AEDisposeDesc( &objTokenDesc );
  180.     
  181.     return err;
  182. } // HandleGetData
  183.  
  184.  
  185. // Get the actual data for a text token - rather than just offset and length
  186. // used internally.
  187.  
  188. OSErr    GetTextTextProperty(TextToken* theToken, AEDesc *result)
  189. {
  190.     TEHandle    aTEH;
  191.     short        anOffset,
  192.                 aLength;
  193.     OSErr        err;
  194.     
  195.     aTEH = TEHandleFromTextToken(theToken);
  196.     anOffset = theToken->tokenOffset;
  197.     aLength = theToken->tokenLength;
  198.     
  199.     err = BuildStyledTextDesc(aTEH, anOffset, aLength, result);
  200.  
  201.     return(err);
  202. }
  203.  
  204. // -----------------------------------------------------------------------
  205. //    Name:         GetTextProperty
  206. //    Purpose:    Fills result with the requested text property.
  207. // -----------------------------------------------------------------------
  208.  
  209. OSErr GetTextProperty(const AEDesc *theTokenDesc, AEDesc *result)
  210. {
  211.     DPtr          theDocument;
  212.     TEHandle      theHTE;
  213.     Str255        fontName;
  214.     TextStyle     theTextStyle;
  215.     short         lineHeight;
  216.     short         fontAscent;
  217.     TextPropToken theTextPropToken;
  218.     Size          tokenSize;
  219.     AEDesc        tempDesc;
  220.     OSErr         err;
  221.     
  222.     err = AECoerceDesc(theTokenDesc, typeMyTextProp, &tempDesc);
  223.     if (noErr != err) goto done;
  224.     
  225.     GetRawDataFromDescriptor(&tempDesc, (Ptr)&theTextPropToken,
  226.                                     sizeof(theTextPropToken), &tokenSize);
  227.  
  228.     // For each property we build a descriptor to be returned as the reply.
  229.             
  230.     theDocument = DPtrFromWindowPtr(theTextPropToken.tokenTextToken.tokenWindow);
  231.     theHTE = theDocument->theText;
  232.     
  233.     TEGetStyle(theTextPropToken.tokenTextToken.tokenOffset - 1, &theTextStyle,
  234.                                                 &lineHeight, &fontAscent, theHTE);
  235.     
  236.     switch (theTextPropToken.tokenProperty)
  237.     {
  238.         case pText:
  239.         case pContents:
  240.             err = GetTextTextProperty(&(theTextPropToken.tokenTextToken), result);
  241.             break;
  242.             
  243.         case pFont: 
  244.             GetFontName(theTextStyle.tsFont, fontName);
  245.             
  246.             err = AECreateDesc(typeChar,  (Ptr)&fontName[1], fontName[0], result);
  247.             break;
  248.         
  249.         case pTextStyles: 
  250.             err = BuildTextStylesDesc(theTextStyle.tsFace, result);
  251.             break;
  252.  
  253.         case pPointSize: 
  254.             err = CreateOffsetDescriptor(theTextStyle.tsSize, result);
  255.             break;
  256.  
  257.         case pScriptTag: 
  258.             err = CreateOffsetDescriptor(smSystemScript, result);
  259.             break;
  260.         
  261.         case pColor: 
  262.             err = AECreateDesc(typeRGBColor, (Ptr)&theTextStyle.tsColor,
  263.                                         sizeof(theTextStyle.tsColor), result);
  264.             break;
  265.             
  266.         case pLength:
  267.             tokenSize = theTextPropToken.tokenTextToken.tokenLength;
  268.             err = AECreateDesc(typeInteger, (Ptr)&tokenSize,
  269.                                 sizeof(tokenSize), result);
  270.             break;
  271.             
  272.         case pOffset:
  273.             tokenSize = theTextPropToken.tokenTextToken.tokenOffset;
  274.             err = AECreateDesc(typeInteger, (Ptr)&tokenSize,
  275.                                 sizeof(tokenSize), result);
  276.             break;
  277.             
  278.         default:
  279.             err = errAEEventNotHandled;
  280.     }
  281.  
  282. done:
  283.     if (tempDesc.dataHandle)
  284.         AEDisposeDesc(&tempDesc);
  285.     
  286.     return(err);
  287. } // GetTextProperty
  288.  
  289.  
  290. // -----------------------------------------------------------------------
  291. //        Name:             GetWindowProperty
  292. //        Purpose:        Fills result with the requested window property.
  293. // -----------------------------------------------------------------------
  294.  
  295. OSErr    GetWindowProperty(const AEDesc *theTokenDesc, AEDesc *result)
  296. {             
  297.     WindowPropToken theWindowPropToken;
  298.     AEDesc          tempDesc = {typeNull, NULL};
  299.     Size            tokenSize;
  300.     OSErr           err;
  301.     
  302.     err = AECoerceDesc( theTokenDesc, typeMyWindowProp, &tempDesc );
  303.     if (noErr != err) goto done;
  304.     
  305.     GetRawDataFromDescriptor(&tempDesc, (Ptr)&theWindowPropToken,
  306.                                 sizeof(theWindowPropToken),  &tokenSize);
  307.                                 
  308.     err = GetWindowTokenProperty( &theWindowPropToken, result );
  309.  
  310. done:
  311.     (void)AEDisposeDesc( &tempDesc );
  312.             
  313.     return(err);
  314. } // GetWindowProperty
  315.  
  316.  
  317. OSErr    GetWindowTokenProperty( WindowPropToken* theToken, AEDesc *result )
  318. {
  319.     DescType            aType;
  320.     Rect                aRect;
  321.     Boolean                aBoolean;
  322.     Str255                aString;
  323.     long                aLong;
  324.     WStateDataHandle    stateHandle;
  325.     OSErr                err;
  326.  
  327.     switch( theToken->tokenProperty )
  328.     {
  329.         case pClass:
  330.         case pDefaultType:    // ?
  331.             aType = cWindow;
  332.             err = AECreateDesc(typeType, (Ptr)&aType, sizeof(aType), result);
  333.             break;
  334.  
  335.         case pBestType:
  336.             if ( IsDocumentWindow( theToken->tokenWindowToken.tokenWindow ) )
  337.                 aType = cDocument;
  338.             else
  339.                 aType = cWindow;
  340.  
  341.             err = AECreateDesc(typeType, (Ptr)&aType, sizeof(aType), result);
  342.             break;
  343.         
  344.         case pBounds:
  345.             aRect = (*((WindowPeek)theToken->tokenWindowToken.tokenWindow)->strucRgn)->rgnBBox;
  346.             err = AECreateDesc(typeQDRectangle, (Ptr)&aRect, sizeof(aRect), result);
  347.             break;
  348.             
  349.         case pVisible:
  350.             aBoolean = IsVisible( theToken->tokenWindowToken.tokenWindow );
  351.             err = AECreateDesc(typeBoolean, (Ptr)&aBoolean, sizeof(aBoolean), result);
  352.             break;
  353.             
  354.         case pHasCloseBox:
  355.             aBoolean = ((WindowPeek)theToken->tokenWindowToken.tokenWindow)->goAwayFlag;
  356.             err = AECreateDesc(typeBoolean, (Ptr)&aBoolean, sizeof(aBoolean), result);
  357.             break;
  358.             
  359.         case pIsZoomable:
  360.             aBoolean = ((WindowPeek)theToken->tokenWindowToken.tokenWindow)->spareFlag;
  361.             err = AECreateDesc(typeBoolean, (Ptr)&aBoolean, sizeof(aBoolean), result);
  362.             break;
  363.             
  364.         case pIsZoomed:
  365.             if (((WindowPeek)theToken->tokenWindowToken.tokenWindow)->spareFlag)
  366.             {
  367.                 stateHandle = (WStateDataHandle)((WindowPeek)theToken->tokenWindowToken.tokenWindow)->dataHandle;
  368.             
  369.                 HLock((Handle)stateHandle);
  370.                 aBoolean = ! EqualRect(&(*stateHandle)->userState, &(*stateHandle)->stdState);
  371.                 HUnlock((Handle)stateHandle);
  372.             }
  373.             else
  374.                 aBoolean = false;
  375.                             
  376.             err = AECreateDesc(typeBoolean, (Ptr)&aBoolean, sizeof(aBoolean), result);
  377.             break;
  378.         
  379.         case pName:
  380.             GetWTitle(theToken->tokenWindowToken.tokenWindow, aString);
  381.             err = AECreateDesc(typeChar, (Ptr)&aString[1], aString[0], result);
  382.             break;
  383.             
  384.         case pIndex:
  385.             aLong = GetWindowIndex( theToken->tokenWindowToken.tokenWindow );
  386.             err = AECreateDesc(typeLongInteger, (Ptr)&aLong, sizeof(aLong), result);
  387.             break;
  388.     
  389.         default:
  390.             err = errAEEventNotHandled;
  391.     }
  392.     
  393.     return(err);
  394. }
  395.  
  396.  
  397. OSErr    GetDocumentProperty( const AEDesc *theTokenDesc, DescType theWantType, AEDesc *result )
  398. {
  399.     WindowPropToken theWindowPropToken;
  400.     AEDesc          tempDesc = {typeNull, NULL};
  401.     Size            tokenSize;
  402.     OSErr           err;
  403.     
  404.     err = AECoerceDesc( theTokenDesc, typeMyDocumentProp, &tempDesc );
  405.     if (noErr != err) goto done;
  406.     
  407.     GetRawDataFromDescriptor( &tempDesc, (Ptr)&theWindowPropToken,
  408.                                 sizeof( theWindowPropToken ),  &tokenSize );
  409.     
  410.     err = GetDocumentTokenProperty( &theWindowPropToken, theWantType, result );
  411.  
  412. done:
  413.     (void)AEDisposeDesc( &tempDesc );
  414.             
  415.     return(err);
  416. }
  417.  
  418.  
  419. OSErr    GetDocumentTokenProperty( WindowPropToken* theToken, DescType theWantType, AEDesc *result )
  420. {
  421.     AEDesc            aDesc = { typeNull, NULL };
  422.     DescType        aType;
  423.     DescType        aLong;
  424.     Boolean         aBoolean;
  425.     DPtr            aDoc;
  426.     TEHandle        theHTE;
  427.     Handle          thePGXHandle;
  428. //    Str255            aPStr;
  429.     OSErr           err;
  430.  
  431.     aDoc = DPtrFromWindowPtr( theToken->tokenWindowToken.tokenWindow );
  432.     
  433.     switch ( theToken->tokenProperty )
  434.     {
  435.         case pBestType:
  436.         case pClass:
  437.         case pDefaultType:
  438.             aType = cDocument;
  439.             err = AECreateDesc( typeType, (Ptr)&aType, sizeof(aType), result );
  440.         break;
  441.             
  442.         case pText:
  443.         case pContents:
  444.             theHTE = aDoc->theText;
  445.             err = BuildStyledTextDesc(theHTE, 1, (**theHTE).teLength, result);
  446.             break;
  447.  
  448.         case pIsModified:
  449.             aBoolean = aDoc->dirty;
  450.             err = AECreateDesc(typeBoolean, (Ptr)&aBoolean, sizeof( aBoolean ), result);
  451.             break;
  452.             
  453.         case pIndex:
  454.             aLong = GetDocumentIndex( theToken->tokenWindowToken.tokenWindow );
  455.             err = AECreateDesc(typeLongInteger, (Ptr)&aLong, sizeof(aLong), result);
  456.             break;
  457.             
  458.         case pPageSetup:
  459.             if (! gGXIsPresent)
  460.             {
  461.                 HLock((Handle)aDoc->thePrintSetup);
  462.                 err = AECreateDesc(typeTPrint, (Ptr)*(aDoc->thePrintSetup),
  463.                                                                 sizeof(TPrint), result);
  464.                 HUnlock((Handle)aDoc->thePrintSetup);
  465.             }
  466.             else
  467.                 err = errAEEventNotHandled;                         
  468.             break;
  469.  
  470.         case pGXPageSetup:
  471.             if ( gGXIsPresent )
  472.             {
  473.                 thePGXHandle = NewHandle( 0 );
  474.                 GXFlattenJobToHdl( aDoc->documentJob, thePGXHandle );
  475.     
  476.                 HLock( thePGXHandle );
  477.                 
  478.                 err = AECreateDesc( typeTPrint, *thePGXHandle,
  479.                                         GetHandleSize(thePGXHandle), result );
  480.                                                              
  481.                 HUnlock( thePGXHandle );                                                                             
  482.                 DisposeHandle( thePGXHandle );
  483.             }
  484.             else
  485.                 err = errAEEventNotHandled;                     
  486.             break;
  487.             
  488.         case pSelection:
  489.             err = MakeSelectedTextObj( theToken->tokenWindowToken.tokenWindow,
  490.                                                                  aDoc->theText, result );
  491.             break;
  492.  
  493.         case pScript:
  494.             if ( kOSANullScript == aDoc->theScriptID )
  495.             {
  496.                 err = errAENoSuchObject;
  497.                 goto done;
  498.             }
  499.             
  500.             err = GetScriptDesc( aDoc->theScriptID, theWantType, result );
  501.             break;
  502.  
  503.         default:
  504.             err = GetWindowTokenProperty( theToken, result );
  505.     }
  506.  
  507. done:
  508.     (void)AEDisposeDesc( &aDesc );
  509.             
  510.     return err;
  511. }
  512.  
  513. // -----------------------------------------------------------------------
  514. //        Name:             GetApplicationProperty
  515. //        Purpose:        Fills result with the requested application property.
  516. // -----------------------------------------------------------------------
  517.      
  518. OSErr    GetApplicationProperty( const AEDesc *theTokenDesc, DescType theWantType, AEDesc *result )
  519. {
  520.     Boolean                isFront;
  521.     AppPropToken        theAppPropToken;
  522.     AEDesc                aDesc = {typeNull, NULL},
  523.                         nullDesc = {typeNull, NULL};
  524.     Size                tokenSize;
  525.     DescType            theType;
  526.       short                refNum;
  527.     Handle                aHandle;
  528.       OSErr                err;
  529.     
  530.     err = AECoerceDesc(theTokenDesc, typeMyApplProp, &aDesc);
  531.     if (noErr != err) goto done;
  532.     
  533.     GetRawDataFromDescriptor(&aDesc, (Ptr)&theAppPropToken,
  534.                                         sizeof(theAppPropToken), &tokenSize);
  535.       
  536.     switch ( theAppPropToken.tokenProperty )
  537.     {
  538.         case pBestType:      // Return the null descriptor representing
  539.         case pDefaultType:    // the application.
  540.             err = AEDuplicateDesc(&nullDesc, result);
  541.             break;
  542.         
  543.         case pClass:
  544.             theType = cApplication;
  545.             err = AECreateDesc(typeType, (Ptr)&theType, sizeof(DescType), result);
  546.             break;
  547.         
  548.         case pName:
  549.                 // We got the name and FSSpec for our application
  550.                 //  in InitApplicationRec().
  551.             err = AECreateDesc( typeChar, (Ptr)&gAppRec.theName[1], gAppRec.theName[0], result );
  552.             break;
  553.         
  554.         case pIsFrontProcess:
  555.             isFront = ! gInBackground;
  556.             err = AECreateDesc(typeBoolean, (Ptr)&isFront, sizeof(isFront), result);
  557.             break;
  558.  
  559.         case pVersion:
  560.             refNum = CurResFile();    // save current resource
  561.             UseResFile(gRefNum);    // set this resource to be current
  562.             aHandle = (Handle)Get1Resource((ResType)'vers', 1);
  563.             HLock(aHandle);
  564.             err = AECreateDesc(typeVersion, *aHandle, GetHandleSize(aHandle), result);
  565.             HUnlock(aHandle);
  566.             UseResFile(refNum);     // reset back to resource previously set
  567.             break;
  568.             
  569.         case pResults:
  570.             err = MakeDocumentObj( GetResultsWindPtr( ), result );
  571.             break;
  572.  
  573.         case pScript:
  574.             if ( kOSANullScript == gAppRec.theScriptID )
  575.             {
  576.                 err = errAENoSuchObject;
  577.                 goto done;
  578.             }
  579.             
  580.             err = GetScriptDesc( gAppRec.theScriptID, theWantType, result );
  581.             break;
  582.  
  583.         default:   // We don't handle the requested property.
  584.             err = errAEEventNotHandled;
  585.     }
  586.  
  587. done:
  588.     (void)AEDisposeDesc( &aDesc );
  589.             
  590.     return err;
  591. } // GetApplicationProperty
  592.  
  593.  
  594. OSErr    GetMenuProperty( const AEDesc *theTokenDesc, DescType theWantType, AEDesc *result )
  595. {
  596.     Str255                aPStr;
  597.     MenuPropToken        thePropToken;
  598.     MenuItemToken        aMenuItemToken;
  599.     AEDesc                aDesc = {typeNull, NULL};
  600.     Size                tokenSize;
  601.     DescType            aType;
  602.     MenuScriptRecPtr    aMenuRecPtr;
  603.       OSErr                err;
  604.     
  605.     err = AECoerceDesc( theTokenDesc, typeMyMenuProp, &aDesc );
  606.     if (noErr != err) goto done;
  607.     
  608.     GetRawDataFromDescriptor( &aDesc, (Ptr)&thePropToken,
  609.                                         sizeof( thePropToken ), &tokenSize );
  610.       
  611.     switch ( thePropToken.tokenProperty )
  612.     {
  613.         case pBestType:
  614.         case pDefaultType:
  615.         case pClass:
  616.             aType = cMenu;
  617.             err = AECreateDesc( typeType, (Ptr)&aType, sizeof( DescType ), result );
  618.             break;
  619.         
  620.         case pName:
  621.             GetMenuName( &thePropToken.token, aPStr );
  622.  
  623.             err = AECreateDesc( typeChar, (Ptr)&aPStr[1], aPStr[0], result );
  624.             break;
  625.             
  626.         case pMenuID:
  627.             err = AECreateDesc( typeShortInteger, (Ptr)&thePropToken.token.tokenID,
  628.                                             sizeof( thePropToken.token.tokenID ), result );
  629.             break;
  630.  
  631.         case pScript:
  632.                 // Get a Ptr to the script for the whole menu
  633.             aMenuRecPtr = GetMenuScriptRecPtr( thePropToken.token.tokenID * 32 );
  634.             if ( ! aMenuRecPtr || kOSANullScript == aMenuRecPtr->theScriptID )
  635.             {
  636.                 err = errAENoSuchObject;
  637.                 goto done;
  638.             }
  639.             
  640.             err = GetScriptDesc( aMenuRecPtr->theScriptID, theWantType, result );
  641.             break;
  642.             
  643.             
  644.         case pSelection:
  645.             aMenuItemToken.tokenItem = GetScriptActiveItem( );
  646.             
  647.             if ( 0 == aMenuItemToken.tokenItem )
  648.                 aMenuItemToken.tokenItem = 1;
  649.             
  650.             if ( 0 != aMenuItemToken.tokenItem )    
  651.             {                    // A selection is only current while executing a command
  652.                                 //  that has an associated script.
  653.                 aMenuItemToken.tokenMenuToken = thePropToken.token;
  654.                 err = MakeMenuItemSpecifier( &aMenuItemToken, result );
  655.             }
  656.             else
  657.                 err = errAENoSuchObject;
  658.             break;
  659.  
  660.         default:   // We don't handle the requested property.
  661.             err = errAEEventNotHandled;
  662.     }
  663.  
  664. done:
  665.     (void)AEDisposeDesc( &aDesc );
  666.             
  667.     return(err);
  668. }
  669.  
  670.  
  671. OSErr    GetMenuItemProperty( const AEDesc *theTokenDesc, DescType theWantType, AEDesc *result )
  672. {
  673.     Str255                aPStr;
  674.     MenuItemPropToken    thePropToken;
  675.     AEDesc                aDesc = {typeNull, NULL};
  676.     Size                tokenSize;
  677.     DescType            aType;
  678.     MenuScriptRecPtr    aMenuRecPtr;
  679.       OSErr                err;
  680.     
  681.     err = AECoerceDesc( theTokenDesc, typeMyMenuItemProp, &aDesc );
  682.     if (noErr != err) goto done;
  683.     
  684.     GetRawDataFromDescriptor( &aDesc, (Ptr)&thePropToken,
  685.                                         sizeof( thePropToken ), &tokenSize );
  686.       
  687.     switch ( thePropToken.tokenProperty )
  688.     {
  689.         case pBestType:      // Return the null descriptor representing
  690.         case pDefaultType:    // the application.
  691.         case pClass:
  692.             aType = cMenuItem;
  693.             err = AECreateDesc( typeType, (Ptr)&aType, sizeof( DescType ), result );
  694.             break;
  695.         
  696.         case pName:
  697.             GetMenuItemName( &thePropToken.token, aPStr );
  698.  
  699.             err = AECreateDesc( typeChar, (Ptr)&aPStr[1], aPStr[0], result );
  700.             break;
  701.             
  702.         case pItemNumber:
  703.             err = AECreateDesc( typeShortInteger, (Ptr)&thePropToken.token.tokenItem,
  704.                                         sizeof( thePropToken.token.tokenItem ), result );
  705.             break;
  706.             
  707.         case pEnabled:
  708.             err = errAEEventNotHandled;
  709.             break;
  710.  
  711.         case pScript:
  712.                 // Get a Ptr to the script for the menu item
  713.             aMenuRecPtr = GetMenuScriptRecPtr( thePropToken.token.tokenMenuToken.tokenID * 32
  714.                                                 + thePropToken.token.tokenItem );
  715.             if ( ! aMenuRecPtr || kOSANullScript == aMenuRecPtr->theScriptID )
  716.             {
  717.                 err = errAENoSuchObject;
  718.                 goto done;
  719.             }
  720.             
  721.             err = GetScriptDesc( aMenuRecPtr->theScriptID, theWantType, result );
  722.             break;
  723.  
  724.         default:   // We don't handle the requested property.
  725.             err = errAEEventNotHandled;
  726.     }
  727.  
  728. done:
  729.     (void)AEDisposeDesc( &aDesc );
  730.             
  731.     return(err);
  732. }
  733.  
  734.